package arithmetic;

import java.util.HashSet;

import com.google.common.collect.Sets;

/**
 * @author jiangfeng on 2021/11/12
 */
public class Yuanshen {
    /**
     * 问题描述. 一个机关有四个滑轮,已知可显示数字为0,1,2,3. 每次扭动可以加1,四进制.  各滑轮相互关联,不能独立调整,扭动其中一个其首尾会被一起调整.<p>
     * 如: 初始为0 0 0 0, 扭动第一个会变成: 1 1 0 1, 继续扭动第二个会变成: 2 2 1 1,继续再扭动第四个会变成: 3 2 2 2,<p>
     *  继续再扭动第一个会变成 0 3 2 3
     *
     * 已知其初始数字如下,问:若需要让所有滑轮归0,需要扭动各位置滑轮多少下?* <p>
     * 1 0 1 0.
     */

    public static Atomic a = null;
    public static Atomic b = null;
    public static Atomic c = null;
    public static Atomic d = null;

    public static void  init(){
        a = new Atomic(1);
        b = new Atomic(0);
        c = new Atomic(1);
        d = new Atomic(0);
    }

    /**
     * 暴力枚举法:总共有4*4*4*4 =256种可能
     * @param args
     */
    public static void main(String[] args) {
        // 总可能次数 4* 4*4 *4
        //16*16= 256次 穷举法

        HashSet<String> objects = Sets.newHashSet();

        int temp =0;
        for (int i = 0; i < 4; i++) {
            init();
            addA(i);
            for (int j = 0; j < 4; j++) {
                addB(j);
                for (int k = 0; k < 4; k++) {
                    addC(k);
                    for (int l = 0; l < 4; l++) {
                        addD(l);
                        System.out.print((temp++)+" i:" + i + " j:" + j + " k:" + k + " l:" + l);
                        String result ="  ";
                        result+= a + " " + b + " " + c + " " + d;
                        System.out.print(result);
                        if (a.isSuccess() && b.isSuccess() && c.isSuccess() && d.isSuccess()) {
                            System.out.print("这是正确:  ");
                        }
                        objects.add(result);
                        System.out.println();
                    }
                }
            }
        }
        System.out.println(objects.size());

    }

    public static void randAdd(int n) {
        n++;
        if (n > 4) {
            n = 0;
        }
    }

    public static void addA(int rand) {
        for (int i = 0; i < rand; i++) {
            d.add();
            a.add();
            b.add();
        }
    }


    public static void addB(int rand) {
        for (int i = 0; i < rand; i++) {
            a.add();
            b.add();
            c.add();
        }
    }

    public static void addC(int rand) {
        for (int i = 0; i < rand; i++) {
            b.add();
            c.add();
            d.add();
        }
    }

    public static void addD(int rand) {
        for (int i = 0; i < rand; i++) {
            c.add();
            d.add();
            a.add();
        }
    }


    public static class Atomic {
        public Atomic(int n) {
            this.num = n;
        }


        @Override
        public String toString() {
            return Integer.toString(this.num);
        }

        int num;

        public boolean isSuccess(){
            return this.num ==0;
        }

        public void add() {
            this.num = this.num + 1;
            if (this.num >= 4) {
                this.num = 0;
            }
        }
    }


}
